Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🌱 Add NamingStrategy to KubeadmControlPlane #11123

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

adilGhaffarDev
Copy link
Contributor

@adilGhaffarDev adilGhaffarDev commented Aug 31, 2024

What this PR does / why we need it:

Which issue(s) this PR fixes (optional, in fixes #<issue number>(, fixes #<issue_number>, ...) format, will close the issue(s) when PR gets merged):
Fixes part of #10577

@k8s-ci-robot
Copy link
Contributor

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@k8s-ci-robot k8s-ci-robot added do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. labels Aug 31, 2024
@k8s-ci-robot k8s-ci-robot added do-not-merge/needs-area PR is missing an area label size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Aug 31, 2024
@adilGhaffarDev
Copy link
Contributor Author

right now it only has API changes, and the remaining work is in progress, I opened a draft PR so I can get some early inputs.
cc @sbueringer

Copy link
Member

@sbueringer sbueringer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested some changes. Let me know what you think

@adilGhaffarDev adilGhaffarDev force-pushed the kcp-naming-issue-fix/adil branch 3 times, most recently from 0b403b1 to 9aa9eb9 Compare September 3, 2024 14:09
@adilGhaffarDev adilGhaffarDev marked this pull request as ready for review September 3, 2024 14:12
@k8s-ci-robot k8s-ci-robot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Sep 3, 2024
@sbueringer sbueringer added the area/provider/control-plane-kubeadm Issues or PRs related to KCP label Sep 3, 2024
@k8s-ci-robot k8s-ci-robot removed the do-not-merge/needs-area PR is missing an area label label Sep 3, 2024
@@ -228,6 +233,19 @@ type RemediationStrategy struct {
MinHealthyPeriod *metav1.Duration `json:"minHealthyPeriod,omitempty"`
}

// MachineNamingStrategy defines the naming strategy for control plane objects.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// MachineNamingStrategy defines the naming strategy for control plane objects.
// MachineNamingStrategy allows changing the naming pattern used when creating Machines.
// Note: InfraMachines & KubeadmConfigs will use the same name as the corresponding Machines.

@sbueringer
Copy link
Member

lgtm for the API from my side (+/- the godoc nit)

Before I start to review the implementation, @fabriziopandini @chrischdi @mdbooth @lentzi90 Are we fine with the API and does it cover your use cases?

@mdbooth
Copy link
Contributor

mdbooth commented Sep 3, 2024

lgtm for the API from my side (+/- the godoc nit)

Before I start to review the implementation, @fabriziopandini @chrischdi @mdbooth @lentzi90 Are we fine with the API and does it cover your use cases?

@adilGhaffarDev is representing the interests of @lentzi90 while he's away. From my POV, I'm happy if @adilGhaffarDev thinks it covers the use case.

@adilGhaffarDev
Copy link
Contributor Author

Before I start to review the implementation, @fabriziopandini @chrischdi @mdbooth @lentzi90 Are we fine with the API and does it cover your use cases?

@lentzi90 flag was also for machineset and that is also going to be removed after 1.9, can I add same namingStrategy in MchineDeployments too in this same PR?

@adilGhaffarDev
Copy link
Contributor Author

@lentzi90 flag was also for machineset and that is also going to be removed after 1.9, can I add same namingStrategy in MchineDeployments too in this same PR?

I will open separate PR for MDs, as discussed here: #10577 (comment) , @sbueringer please review this one. Also, fuzzing tests are failing in v1alpha APIs, Do you have any idea why they are failing?

@sbueringer
Copy link
Member

@sbueringer please review this one.

I would like to get reviews from other maintainers on the API first. It's not only my call.

@@ -117,6 +117,11 @@ type KubeadmControlPlaneSpec struct {
// The RemediationStrategy that controls how control plane machine remediation happens.
// +optional
RemediationStrategy *RemediationStrategy `json:"remediationStrategy,omitempty"`

// MachineNamingStrategy allows changing the naming pattern used when creating Machines.
// Note: InfraMachines & KubeadmConfigs will use the same name as the corresponding Machines.
Copy link
Member

@neolit123 neolit123 Sep 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Note: InfraMachines & KubeadmConfigs will use the same name as the corresponding Machines.
// InfraMachines & KubeadmConfigs will use the same name as the corresponding Machines.

there is no need for the Note: here. this is just another sentence providing the additional context.

@@ -228,6 +233,20 @@ type RemediationStrategy struct {
MinHealthyPeriod *metav1.Duration `json:"minHealthyPeriod,omitempty"`
}

// MachineNamingStrategy allows changing the naming pattern used when creating Machines.
// Note: InfraMachines & KubeadmConfigs will use the same name as the corresponding Machines.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Note: InfraMachines & KubeadmConfigs will use the same name as the corresponding Machines.
// InfraMachines & KubeadmConfigs will use the same name as the corresponding Machines.

// * `.kubeadmcontrolplane.name`: The name of the KubeadmControlPlane object.
// * `.random`: A random alphanumeric string, without vowels, of length 5.
// +optional
Template *string `json:"template,omitempty"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are there benefits of having this as a pointer field?

Copy link
Member

@sbueringer sbueringer Sep 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, just a mistake I copied from somewhere else. Fine to drop the pointer

if kcp.Spec.MachineNamingStrategy != nil && kcp.Spec.MachineNamingStrategy.Template != nil {
nameTemplate = *kcp.Spec.MachineNamingStrategy.Template
}
generatedMachineName, err := topologynames.KCPMachineNameGenerator(nameTemplate, kcp.Name).GenerateName()
Copy link
Member

@neolit123 neolit123 Sep 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the templated string exceeds 63 characters, it will be trimmed to 58 characters and will
get concatenated with a random suffix of length 5.

should there be an explicit test case for this on the MachineNamingStrategy level?
presumably https://github.com/kubernetes-sigs/cluster-api/blob/90c4712f67bf21fce52e07a57488f62497306699/internal/topology/names/names.go#L40C30-L40C43 has tests, but might be worth testing on this level too.

@k8s-ci-robot k8s-ci-robot removed the size/M Denotes a PR that changes 30-99 lines, ignoring generated files. label Sep 10, 2024
@k8s-ci-robot k8s-ci-robot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Sep 10, 2024
@adilGhaffarDev adilGhaffarDev force-pushed the kcp-naming-issue-fix/adil branch 3 times, most recently from 3ac0057 to c5e36b8 Compare September 10, 2024 14:37
Copy link
Member

@neolit123 neolit123 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Sep 10, 2024
@k8s-ci-robot
Copy link
Contributor

LGTM label has been added.

Git tree hash: 8c506758c47f4cf2c10dbc19e12c368095531f1f

@sbueringer
Copy link
Member

sbueringer commented Sep 10, 2024

@sbueringer please review this one.

I would like to get reviews from other maintainers on the API first. It's not only my call.

/hold
for above

@k8s-ci-robot k8s-ci-robot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Sep 10, 2024
@adilGhaffarDev
Copy link
Contributor Author

@fabriziopandini @chrischdi please take a look when you get time.

Copy link
Member

@fabriziopandini fabriziopandini left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change lgtm to me (just nits & minor improvements).
@JoelSpeed @vincepri for a quick look at the API changes

type MachineNamingStrategy struct {
// Template defines the template to use for generating the names of the Machine objects.
// If not defined, it will fallback to `{{ .kubeadmcontrolplane.name }}-{{ .random }}`.
// If the templated string exceeds 63 characters, it will be trimmed to 58 characters and will
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// If the templated string exceeds 63 characters, it will be trimmed to 58 characters and will
// If the generate name string exceeds 63 characters, it will be trimmed to 58 characters and will

I assume

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

// If the templated string exceeds 63 characters, it will be trimmed to 58 characters and will
// get concatenated with a random suffix of length 5.
// The templating mechanism provides the following arguments:
// * `.kubeadmcontrolplane.name`: The name of the KubeadmControlPlane object.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should provide also cluster name

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay for me

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added clustername too.

want []gomegatypes.GomegaMatcher
}{
{
name: "should return the correct Machine object when creating a new Machine",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add a test case for the default behaviour (no template) and for when the generated name exceeds the lenght

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done, following cases are added:

  • User-defined template
  • template exceeding 63 chars.
  • invalid template
  • no template

We are already testing some cases here: https://github.com/kubernetes-sigs/cluster-api/blob/main/internal/topology/names/names_test.go

},
},
MachineNamingStrategy: &controlplanev1.MachineNamingStrategy{
Template: fmt.Sprintf("%064d", 0),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit

Suggested change
Template: fmt.Sprintf("%064d", 0),
Template: fmt.Sprintf("%064d", 0), // invalid template

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was not invalid; the test was named wrong and is now fixed.
I have added a new test with an invalid template too.

type MachineNamingStrategy struct {
// Template defines the template to use for generating the names of the Machine objects.
// If not defined, it will fallback to `{{ .kubeadmcontrolplane.name }}-{{ .random }}`.
// If the templated string exceeds 63 characters, it will be trimmed to 58 characters and will
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if the combination of the name and random suffix is 64 characters? Do we then trim and add a new random suffix?

Copy link
Member

@sbueringer sbueringer Sep 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes

	if len(name) > maxNameLength {
		name = name[:maxGeneratedNameLength] + utilrand.String(randomLength)
	}

(maxNameLength is 63)

// get concatenated with a random suffix of length 5.
// The templating mechanism provides the following arguments:
// * `.kubeadmcontrolplane.name`: The name of the KubeadmControlPlane object.
// * `.random`: A random alphanumeric string, without vowels, of length 5.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why expose this rather than always appending -<random 5 chars> at the end of the string?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see the following reasons:

  • We already have namingStrategies in the ClusterClass that work the same way as the one introduced here (so consistency would be nice)
    • In that case we use the namingStrategies to calculate control plane / MD and MP names. In these cases it was desirable to not always end up with a random suffix. E.g. folks wanted to be able to have KCP names that are identical to Cluster names
  • Another case would be if folks have the (admittedly strange) use case that the random part shouldn't be at the end of the name (there was one (!) person asking for it in Slack, they wanted a random prefix for some reason, xref: https://kubernetes.slack.com/archives/C8TSNPY4T/p1724389852680579)

Comment on lines 249 to 250
// The templating mechanism provides the following arguments:
// * `.kubeadmcontrolplane.name`: The name of the KubeadmControlPlane object.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that bullet points look great here, but the formatting does not transfer well to kubectl explain, review the CRD description of this field and you'll see the formatting is all squashed. Instead, use full sentences to explain the same context.

Something along the lines of

// The template allows the following variables ".kubadmcontrolplane.name", ".something.else" and ".random".
// The variable ".kubeadmcontrolplane.name" retrieves the name of the KubeadmControlPlane object that owns the Machines being created.
// The variable ".random" is substituted with a 5 character alphanumeric string on creation.
// Variables in the template must be enclosed in double braces ("{{ <variable> }}").

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

// * `.kubeadmcontrolplane.name`: The name of the KubeadmControlPlane object.
// * `.random`: A random alphanumeric string, without vowels, of length 5.
// +optional
Template string `json:"template,omitempty"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should impose a maximal length on this string, you know that the rendered value must not exceed 63 chars, so it needs to be at least that in length, assuming a worst case, the value of any substituted variable could be 1 character right?

So it needs to be 62 plus the length in the template of representing the longest variable. Currently that is {{ .kubeadmcontrolplane.name }} which is 31 characters, so, a limit of 93 would be suitable presently

Copy link
Member

@sbueringer sbueringer Sep 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can do this slightly better and easier. We already have similar validation for the other namingStrategies we have:

name, err := names.ControlPlaneNameGenerator(*clusterClass.Spec.ControlPlane.NamingStrategy.Template, "cluster").GenerateName()

So we can verify:

  • that the template actually renders
  • that the rendered output is a valid name
  • use the minimal length for our parameters and then check if the generated output is too long
    • Not sure if we actually ever hit that case, because we have that safeguard that we just cut if rendered string gets too long. So I think we don't need this validation?
    • Note: You can do a bunch of stuff in templates, so I think the template can be a lot longer without actually leading to long rendered values.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I am a bit confused, do we need restrictions on minimum chars too for the generated name?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JoelSpeed wdyt based on my comment above?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that sounds reasonable yes! So that would be webhook based validation, you should still also include an API side maximum length though (since we can calculate a reasonable maximum)

Having maximum lengths on all fields is good practice and helps with the runtime cost analysis that's built into the CEL libraries, should we ever get to using those.

You can add length limits when the API is introduced, restricting them later is harder

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yeah, good point. I forgot the CEL part

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The validation webhook that is in clusterclass I believe is checking all the things needed. I have added the same here, let me know if anything needs to be updated.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can see that the webhook is checking the template, but, I think we do still want to have a length limit as a marker on the API field here, for completeness

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added the marker for max length please check.

// * `.kubeadmcontrolplane.name`: The name of the KubeadmControlPlane object.
// * `.random`: A random alphanumeric string, without vowels, of length 5.
// +optional
Template string `json:"template,omitempty"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to impose a pattern validation on this string?

Is there any admission time validation at present that checks that this compiles and would produce a valid template?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch!
(I didn't review the implementation myself yet, only the API)

We should have a similar validation than what we have for other naming strategies:

name, err := names.ControlPlaneNameGenerator(*clusterClass.Spec.ControlPlane.NamingStrategy.Template, "cluster").GenerateName()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added the validation webhook, please check.

@k8s-ci-robot k8s-ci-robot removed the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Oct 1, 2024
@k8s-ci-robot
Copy link
Contributor

New changes are detected. LGTM label has been removed.

@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please ask for approval from neolit123. For more information see the Kubernetes Code Review Process.

The full list of commands accepted by this bot can be found here.

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Oct 1, 2024
@adilGhaffarDev adilGhaffarDev force-pushed the kcp-naming-issue-fix/adil branch 2 times, most recently from f316bd3 to 9049aaa Compare October 1, 2024 12:41
Signed-off-by: Muhammad Adil Ghaffar <muhammad.adil.ghaffar@est.tech>
@k8s-ci-robot
Copy link
Contributor

@adilGhaffarDev: The following test failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
pull-cluster-api-test-main 94c96ca link true /test pull-cluster-api-test-main

Full PR test history. Your PR dashboard. Please help us cut down on flakes by linking to an open issue when you hit one in your PR.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@adilGhaffarDev
Copy link
Contributor Author

@adilGhaffarDev: The following test failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:
Test name Commit Details Required Rerun command
pull-cluster-api-test-main 94c96ca link true /test pull-cluster-api-test-main

Full PR test history. Your PR dashboard. Please help us cut down on flakes by linking to an open issue when you hit one in your PR.

@sbueringer fuzz tests for v1alpha are failing, what do I need to add to fix these tests?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/provider/control-plane-kubeadm Issues or PRs related to KCP cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants